<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <meta name="generator" content="VuePress 2.0.0-beta.66">
    <style>
      :root {
        --c-bg: #fff;
      }
      html.dark {
        --c-bg: #22272e;
      }
      html, body {
        background-color: var(--c-bg);
      }
    </style>
    <script>
      const userMode = localStorage.getItem('vuepress-color-scheme');
			const systemDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
			if (userMode === 'dark' || (userMode !== 'light' && systemDarkMode)) {
				document.documentElement.classList.toggle('dark', true);
			}
    </script>
    <link rel="icon" href="https://cdn.pixabay.com/animation/2022/08/05/07/12/07-12-14-597_512.gif"><title>Vue | PERSIST</title><meta name="description" content="三剑客、Vue、React、...">
    <link rel="preload" href="/blogs/assets/style-3126903c.css" as="style"><link rel="stylesheet" href="/blogs/assets/style-3126903c.css">
    <link rel="modulepreload" href="/blogs/assets/app-5598dde8.js"><link rel="modulepreload" href="/blogs/assets/vue_notes.html-cbe8ffc8.js"><link rel="modulepreload" href="/blogs/assets/vue_notes.html-096e3b77.js"><link rel="prefetch" href="/blogs/assets/index.html-d9b814f4.js" as="script"><link rel="prefetch" href="/blogs/assets/css.html-38c59cab.js" as="script"><link rel="prefetch" href="/blogs/assets/css3.html-28b2b602.js" as="script"><link rel="prefetch" href="/blogs/assets/html.html-fda41b1c.js" as="script"><link rel="prefetch" href="/blogs/assets/html5.html-b423fb46.js" as="script"><link rel="prefetch" href="/blogs/assets/JavaScript.html-ea762ff0.js" as="script"><link rel="prefetch" href="/blogs/assets/TypeScript.html-8e165f09.js" as="script"><link rel="prefetch" href="/blogs/assets/base.html-84d926c4.js" as="script"><link rel="prefetch" href="/blogs/assets/bigscreen.html-5524caa6.js" as="script"><link rel="prefetch" href="/blogs/assets/react.html-8bfc6f05.js" as="script"><link rel="prefetch" href="/blogs/assets/uniapp.html-02246930.js" as="script"><link rel="prefetch" href="/blogs/assets/vue.html-241f215e.js" as="script"><link rel="prefetch" href="/blogs/assets/handbook.html-6cbaa868.js" as="script"><link rel="prefetch" href="/blogs/assets/React.html-418e631e.js" as="script"><link rel="prefetch" href="/blogs/assets/ReactRouter.html-7e5f06ff.js" as="script"><link rel="prefetch" href="/blogs/assets/Redux.html-5560e17c.js" as="script"><link rel="prefetch" href="/blogs/assets/StudyTutorial.html-b823f3d9.js" as="script"><link rel="prefetch" href="/blogs/assets/uniapp.html-f94e0631.js" as="script"><link rel="prefetch" href="/blogs/assets/Pinia.html-387c093b.js" as="script"><link rel="prefetch" href="/blogs/assets/Vue3.html-16d06532.js" as="script"><link rel="prefetch" href="/blogs/assets/VueApi.html-bb8b9635.js" as="script"><link rel="prefetch" href="/blogs/assets/VueRouter.html-ae38cb38.js" as="script"><link rel="prefetch" href="/blogs/assets/Vuex4.html-7a289a91.js" as="script"><link rel="prefetch" href="/blogs/assets/404.html-f9875e7b.js" as="script"><link rel="prefetch" href="/blogs/assets/index.html-443e75e2.js" as="script"><link rel="prefetch" href="/blogs/assets/css.html-ab74bca3.js" as="script"><link rel="prefetch" href="/blogs/assets/css3.html-77914954.js" as="script"><link rel="prefetch" href="/blogs/assets/html.html-841090be.js" as="script"><link rel="prefetch" href="/blogs/assets/html5.html-4d4eaa91.js" as="script"><link rel="prefetch" href="/blogs/assets/JavaScript.html-099c0d25.js" as="script"><link rel="prefetch" href="/blogs/assets/TypeScript.html-f51a5af3.js" as="script"><link rel="prefetch" href="/blogs/assets/base.html-15ef8c21.js" as="script"><link rel="prefetch" href="/blogs/assets/bigscreen.html-0d51dc7f.js" as="script"><link rel="prefetch" href="/blogs/assets/react.html-eb1112c8.js" as="script"><link rel="prefetch" href="/blogs/assets/uniapp.html-3457663e.js" as="script"><link rel="prefetch" href="/blogs/assets/vue.html-3059cfc3.js" as="script"><link rel="prefetch" href="/blogs/assets/handbook.html-cd96bfb6.js" as="script"><link rel="prefetch" href="/blogs/assets/React.html-659a8167.js" as="script"><link rel="prefetch" href="/blogs/assets/ReactRouter.html-dc674066.js" as="script"><link rel="prefetch" href="/blogs/assets/Redux.html-9f749333.js" as="script"><link rel="prefetch" href="/blogs/assets/StudyTutorial.html-f43ec5ce.js" as="script"><link rel="prefetch" href="/blogs/assets/uniapp.html-9ec54961.js" as="script"><link rel="prefetch" href="/blogs/assets/Pinia.html-1dcc52b7.js" as="script"><link rel="prefetch" href="/blogs/assets/Vue3.html-48a9f634.js" as="script"><link rel="prefetch" href="/blogs/assets/VueApi.html-684b02dc.js" as="script"><link rel="prefetch" href="/blogs/assets/VueRouter.html-6184995c.js" as="script"><link rel="prefetch" href="/blogs/assets/Vuex4.html-1fce3133.js" as="script"><link rel="prefetch" href="/blogs/assets/404.html-8fc28dc8.js" as="script">
  </head>
  <body>
    <div id="app"><!--[--><div class="theme-container"><!--[--><header class="navbar"><div class="toggle-sidebar-button" title="toggle sidebar" aria-expanded="false" role="button" tabindex="0"><div class="icon" aria-hidden="true"><span></span><span></span><span></span></div></div><span><a href="/blogs/" class=""><img class="logo" src="https://cdn.pixabay.com/animation/2022/08/05/07/12/07-12-14-597_512.gif" alt="PERSIST"><span class="site-name can-hide">PERSIST</span></a></span><div class="navbar-items-wrapper" style=""><!--[--><!--]--><nav class="navbar-items can-hide"><!--[--><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="三剑客"><span class="title">三剑客</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="三剑客"><span class="title">三剑客</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>html</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/base/html.html" class="" aria-label="HTML"><!--[--><!--]--> HTML <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/base/html5.html" class="" aria-label="HTML 5"><!--[--><!--]--> HTML 5 <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>css</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/base/css.html" class="" aria-label="CSS"><!--[--><!--]--> CSS <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/base/css3.html" class="" aria-label="CSS 3"><!--[--><!--]--> CSS 3 <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>JavaScript</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/base/JavaScript.html" class="" aria-label="JavaScript"><!--[--><!--]--> JavaScript <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>TypeScript</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/base/TypeScript.html" class="" aria-label="TypeScript"><!--[--><!--]--> TypeScript <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="Vue"><span class="title">Vue</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="Vue"><span class="title">Vue</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Vue</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/Vue3.html" class="" aria-label="Vue"><!--[--><!--]--> Vue <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/VueApi.html" class="" aria-label="Vue API"><!--[--><!--]--> Vue API <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Vue Router</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/VueRouter.html" class="" aria-label="Vue Router"><!--[--><!--]--> Vue Router <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>状态管理</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/Vuex4.html" class="" aria-label="Vuex"><!--[--><!--]--> Vuex <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/Pinia.html" class="" aria-label="Pinia"><!--[--><!--]--> Pinia <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="React"><span class="title">React</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="React"><span class="title">React</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>React</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/React/React.html" class="" aria-label="React"><!--[--><!--]--> React <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>React Router</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/React/ReactRouter.html" class="" aria-label="React Router"><!--[--><!--]--> React Router <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>状态管理</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/React/Redux.html" class="" aria-label="Redux"><!--[--><!--]--> Redux <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="经典案例"><span class="title">经典案例</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="经典案例"><span class="title">经典案例</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>三剑客</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/case/base.html" class="" aria-label="三剑客"><!--[--><!--]--> 三剑客 <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Vue</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/case/vue.html" class="" aria-label="Vue"><!--[--><!--]--> Vue <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>uni-app</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/uniapp/uniapp.html" class="" aria-label="uni-app 教程"><!--[--><!--]--> uni-app 教程 <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/case/uniapp.html" class="" aria-label="uni-app"><!--[--><!--]--> uni-app <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>React</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/case/react.html" class="" aria-label="React"><!--[--><!--]--> React <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>大屏</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/case/bigscreen.html" class="" aria-label="大屏"><!--[--><!--]--> 大屏 <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><a href="/blogs/StudyTutorial/StudyTutorial.md" class="" aria-label="学习教程"><!--[--><!--]--> 学习教程 <!--[--><!--]--></a></div><div class="navbar-item"><a href="/blogs/handbook/handbook.md" class="" aria-label="前端手册"><!--[--><!--]--> 前端手册 <!--[--><!--]--></a></div><div class="navbar-item"><a class="external-link" href="https://gitee.com/fayuanpersist/blogs" rel="noopener noreferrer" target="_blank" aria-label="Gitee"><!--[--><!--]--> Gitee <span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!--[--><!--]--></a></div><!--]--></nav><!--[--><!--]--><button class="toggle-color-mode-button" title="toggle color mode"><svg style="" class="icon" focusable="false" viewBox="0 0 32 32"><path d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6z" fill="currentColor"></path><path d="M5.394 6.813l1.414-1.415l3.506 3.506L8.9 10.318z" fill="currentColor"></path><path d="M2 15.005h5v2H2z" fill="currentColor"></path><path d="M5.394 25.197L8.9 21.691l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 25.005h2v5h-2z" fill="currentColor"></path><path d="M21.687 23.106l1.414-1.415l3.506 3.506l-1.414 1.414z" fill="currentColor"></path><path d="M25 15.005h5v2h-5z" fill="currentColor"></path><path d="M21.687 8.904l3.506-3.506l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 2.005h2v5h-2z" fill="currentColor"></path></svg><svg style="display:none;" class="icon" focusable="false" viewBox="0 0 32 32"><path d="M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z" fill="currentColor"></path></svg></button><form class="search-box" role="search"><input type="search" autocomplete="off" spellcheck="false" value><!----></form></div></header><!--]--><div class="sidebar-mask"></div><!--[--><aside class="sidebar"><nav class="navbar-items"><!--[--><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="三剑客"><span class="title">三剑客</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="三剑客"><span class="title">三剑客</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>html</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/base/html.html" class="" aria-label="HTML"><!--[--><!--]--> HTML <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/base/html5.html" class="" aria-label="HTML 5"><!--[--><!--]--> HTML 5 <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>css</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/base/css.html" class="" aria-label="CSS"><!--[--><!--]--> CSS <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/base/css3.html" class="" aria-label="CSS 3"><!--[--><!--]--> CSS 3 <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>JavaScript</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/base/JavaScript.html" class="" aria-label="JavaScript"><!--[--><!--]--> JavaScript <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>TypeScript</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/base/TypeScript.html" class="" aria-label="TypeScript"><!--[--><!--]--> TypeScript <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="Vue"><span class="title">Vue</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="Vue"><span class="title">Vue</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Vue</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/Vue3.html" class="" aria-label="Vue"><!--[--><!--]--> Vue <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/VueApi.html" class="" aria-label="Vue API"><!--[--><!--]--> Vue API <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Vue Router</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/VueRouter.html" class="" aria-label="Vue Router"><!--[--><!--]--> Vue Router <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>状态管理</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/Vuex4.html" class="" aria-label="Vuex"><!--[--><!--]--> Vuex <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/Vue/Pinia.html" class="" aria-label="Pinia"><!--[--><!--]--> Pinia <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="React"><span class="title">React</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="React"><span class="title">React</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>React</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/React/React.html" class="" aria-label="React"><!--[--><!--]--> React <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>React Router</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/React/ReactRouter.html" class="" aria-label="React Router"><!--[--><!--]--> React Router <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>状态管理</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/React/Redux.html" class="" aria-label="Redux"><!--[--><!--]--> Redux <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="经典案例"><span class="title">经典案例</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="经典案例"><span class="title">经典案例</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>三剑客</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/case/base.html" class="" aria-label="三剑客"><!--[--><!--]--> 三剑客 <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Vue</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/case/vue.html" class="" aria-label="Vue"><!--[--><!--]--> Vue <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>uni-app</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/uniapp/uniapp.html" class="" aria-label="uni-app 教程"><!--[--><!--]--> uni-app 教程 <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/blogs/case/uniapp.html" class="" aria-label="uni-app"><!--[--><!--]--> uni-app <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>React</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/case/react.html" class="" aria-label="React"><!--[--><!--]--> React <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>大屏</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/blogs/case/bigscreen.html" class="" aria-label="大屏"><!--[--><!--]--> 大屏 <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><a href="/blogs/StudyTutorial/StudyTutorial.md" class="" aria-label="学习教程"><!--[--><!--]--> 学习教程 <!--[--><!--]--></a></div><div class="navbar-item"><a href="/blogs/handbook/handbook.md" class="" aria-label="前端手册"><!--[--><!--]--> 前端手册 <!--[--><!--]--></a></div><div class="navbar-item"><a class="external-link" href="https://gitee.com/fayuanpersist/blogs" rel="noopener noreferrer" target="_blank" aria-label="Gitee"><!--[--><!--]--> Gitee <span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!--[--><!--]--></a></div><!--]--></nav><!--[--><!--]--><ul class="sidebar-items"><!--[--><li><p tabindex="0" class="sidebar-item sidebar-heading collapsible">Vue <span class="right arrow"></span></p><ul style="display:none;" class="sidebar-item-children"><!--[--><li><a href="/blogs/Vue/Vue3.html" class="sidebar-item" aria-label="Vue"><!--[--><!--]--> Vue <!--[--><!--]--></a><!----></li><li><a href="/blogs/Vue/VueApi.html" class="sidebar-item" aria-label="Vue API"><!--[--><!--]--> Vue API <!--[--><!--]--></a><!----></li><!--]--></ul></li><li><p tabindex="0" class="sidebar-item sidebar-heading collapsible">Vue Router <span class="right arrow"></span></p><ul style="display:none;" class="sidebar-item-children"><!--[--><li><a href="/blogs/Vue/VueRouter.html" class="sidebar-item" aria-label="Vue Router"><!--[--><!--]--> Vue Router <!--[--><!--]--></a><!----></li><!--]--></ul></li><li><p tabindex="0" class="sidebar-item sidebar-heading collapsible">状态管理 <span class="right arrow"></span></p><ul style="display:none;" class="sidebar-item-children"><!--[--><li><a href="/blogs/Vue/Vuex4.html" class="sidebar-item" aria-label="Vuex"><!--[--><!--]--> Vuex <!--[--><!--]--></a><!----></li><li><a href="/blogs/Vue/Pinia.html" class="sidebar-item" aria-label="Pinia"><!--[--><!--]--> Pinia <!--[--><!--]--></a><!----></li><!--]--></ul></li><!--]--></ul><!--[--><!--]--></aside><!--]--><!--[--><main class="page"><!--[--><!--]--><div class="theme-default-content"><!--[--><!--]--><div><h1 id="vue" tabindex="-1"><a class="header-anchor" href="#vue" aria-hidden="true">#</a> Vue</h1><blockquote><p>渐进式 JavaScript 框架</p></blockquote><p><a href="https://v2.cn.vuejs.org/" target="_blank" rel="noopener noreferrer">Vue2 官网<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a><br><a href="https://cn.vuejs.org/" target="_blank" rel="noopener noreferrer">Vue3 官网<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a><br><a href="https://www.javascriptc.com/vue3js/" target="_blank" rel="noopener noreferrer">vue3 中文文档(备用)<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a><br><a href="https://vue3js.cn/vue-composition-api/" target="_blank" rel="noopener noreferrer">Vue3 组合式api社区文档<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p><div class="custom-container tip"><p class="custom-container-title">预备知识</p><p>文档接下来的内容会假设你对 HTML、CSS 和 JavaScript 已经基本熟悉。如果你对前端开发完全陌生，最好不要直接从一个框架开始进行入门学习——最好是掌握了基础知识再回到这里。你可以通过这篇 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Language_overview" target="_blank" rel="noopener noreferrer">JavaScript 概述<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a>来检验你的 JavaScript 知识水平。如果之前有其他框架的经验会很有帮助，但也不是必须的。</p></div><h2 id="vue-概念" tabindex="-1"><a class="header-anchor" href="#vue-概念" aria-hidden="true">#</a> Vue 概念</h2><blockquote><p>即 <strong>声明式</strong>、<strong>响应式</strong>、<strong>渐进式</strong></p></blockquote><details class="custom-container details"><summary>Vue 概念 <span class="badge tip" style=""><!--[-->介绍<!--]--></span></summary><ul><li><strong>声明式</strong></li></ul><p>Vue 基于标准 HTML 拓展了一套模板语法，使得我们可以声明式地描述最终输出的 HTML 和 JavaScript 状态之间的关系。</p><p>『声明式』是相对于『编程式』而言的。</p><blockquote><ul><li><p>声明式：告诉框架做什么，具体操作由框架完成</p></li><li><p>编程式：自己编写代码完成具体操作</p></li></ul></blockquote><ul><li><strong>响应式</strong></li></ul><p>Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM。</p><p>响应式也叫做数据的双向绑定</p><p><img src="/blogs/assets/data-a641a0ae.png" alt="双向数据绑定原理"></p><ul><li><strong>渐进式</strong></li></ul><p><img src="/blogs/assets/渐进式-72a9c2ac.jpg" alt="渐进式"></p></details><h2 id="vue-组件-核心概念" tabindex="-1"><a class="header-anchor" href="#vue-组件-核心概念" aria-hidden="true">#</a> Vue 组件 核心概念</h2><blockquote><p>Vue 组件 的三大核心概念为：<strong>属性</strong>、<strong>事件</strong>、<strong>插槽</strong></p></blockquote><details class="custom-container details"><summary>Vue 组件 核心概念 <span class="badge tip" style=""><!--[-->介绍<!--]--></span></summary><p><img src="/blogs/assets/vue组件三大核心概念-dac15e66.png" alt="Vue组件 核心概念"></p><p><a href="https://blog.csdn.net/qq_45731083/article/details/123281863" target="_blank" rel="noopener noreferrer">参考文章<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p></details><h2 id="虚拟-dom" tabindex="-1"><a class="header-anchor" href="#虚拟-dom" aria-hidden="true">#</a> 虚拟 DOM</h2><details class="custom-container details"><summary>虚拟 DOM<span class="badge tip" style=""><!--[-->介绍<!--]--></span></summary><p>DOM 是很慢的，其元素非常庞大，页面的性能问题主要由 JS 引起的，大部分都是由 DOM 操作引起的。</p><p><code>虚拟DOM</code><span class="badge tip" style=""><!--[-->优点<!--]--></span></p><p><strong>对真实的元素节点进行抽象，抽象成 VNode（虚拟节点），方便对其进行各种操作：</strong></p><p>直接操作 DOM 来说是有很多的限制的，比如 diff、clone 等等；<br> 可以使用 JavaScript 来表达非常多的逻辑，而对于 DOM 本身来说是非常不方便的；</p><p><strong>其次是方便实现跨平台，包括你可以将 VNode 节点渲染成任意你想要的节点：</strong></p><p>如渲染在 canvas、WebGL、SSR、Native（iOS、Android）上；<br> 并且 Vue 允许你开发属于自己的渲染器（renderer），在其他的平台上渲染；</p><p><strong>虚拟 DOM 的渲染过程</strong></p><p><img src="/blogs/assets/虚拟dom-c4984f03.png" alt="虚拟DOM"></p><p><a href="https://www.cnblogs.com/hexrui/p/15754226.html" target="_blank" rel="noopener noreferrer">参考文章<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p></details><h2 id="vue-三大核心系统" tabindex="-1"><a class="header-anchor" href="#vue-三大核心系统" aria-hidden="true">#</a> Vue 三大核心系统</h2><blockquote><p><strong>Compiler 模块</strong>、<strong>Runtime 模块</strong>、<strong>Reactivity 模块</strong></p></blockquote><details class="custom-container details"><summary>Vue 三大核心系统 <span class="badge tip" style=""><!--[-->介绍<!--]--></span></summary><ul><li><strong>Compiler 模块：编译模板系统；</strong></li><li><strong>Runtime 模块：也可以称之为 Renderer 模块，真正渲染的模块；</strong></li><li><strong>Reactivity 模块：响应式系统；</strong></li></ul><p><img src="/blogs/assets/三大系统-64666b66.png" alt="Vue 三大核心系统"></p><p><a href="https://www.cnblogs.com/hexrui/p/15754226.html" target="_blank" rel="noopener noreferrer">参考文章<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p></details><h2 id="mvx、mvvm-模式" tabindex="-1"><a class="header-anchor" href="#mvx、mvvm-模式" aria-hidden="true">#</a> MVX、MVVM 模式</h2><details class="custom-container details"><summary>MVX、MVVM 模式 <span class="badge tip" style=""><!--[-->介绍<!--]--></span></summary><p>MVC 框架最早出现在 Java 领域，然后慢慢在前端开发中也被提到，后来又出现了 MVP，以及现在最成熟的 MVVM。</p><h3 id="mvx" tabindex="-1"><a class="header-anchor" href="#mvx" aria-hidden="true">#</a> MVX</h3><blockquote><p>X 不是固定的</p></blockquote><ul><li><strong>MVC</strong></li></ul><p>MVC 全名是 Model View Controller，是模型(model)-视图(view)-控制器(controller)的缩写，一种软件设计典范，用一种业务逻辑、数据、界面显示分离的方法组织代码，将业务逻辑聚集到一个部件里面，在改进和个性化定制界面及用户交互的同时，不需要重新编写业务逻辑。</p><ul><li><strong>MVP</strong></li></ul><p>MVP 是单词 Model View Presenter 的首字母的缩写，分别表示数据层、视图层、发布层，它是 MVC 架构的一种演变。</p><ul><li><strong>MVVM</strong></li></ul><p>MVVM(Model View ViewModel)是一种基于 MVC 的设计，开发人员在 HTML 上写一些 Bindings,利用一些指令绑定，就能在 Model 和 ViewModel 保持不变的情况下，很方便的将 UI 设计与业务逻辑分离，从而大大的减少繁琐的 DOM 操作。</p><p><a href="https://www.kancloud.cn/dataoedu/vue/289126" target="_blank" rel="noopener noreferrer">参考文章<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p><h3 id="mvvm-模式" tabindex="-1"><a class="header-anchor" href="#mvvm-模式" aria-hidden="true">#</a> MVVM 模式</h3><p>MVVM 是 Model-View-ViewModel 的缩写，它是一种基于前端开发的架构模式，其核心是提供对 View 和 ViewModel 的双向数据绑定，这使得 ViewModel 的状态改变可以自动传递给 View，即所谓的数据双向绑定。</p><p><img src="https://box.kancloud.cn/eb5c6e9f9bb7107c374dd892f6d7d38f_600x287.png" alt="数据双向绑定"></p><p><strong>Vue 双向绑定原理</strong></p><p><img src="https://box.kancloud.cn/04772e55186c0805646fe1bd1696d5d3_647x334.png" alt="vue 数据双向绑定 原理"></p><p><a href="https://www.kancloud.cn/dataoedu/vue/327305" target="_blank" rel="noopener noreferrer">参考文章<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p></details><h2 id="单文件组件" tabindex="-1"><a class="header-anchor" href="#单文件组件" aria-hidden="true">#</a> 单文件组件</h2><p>单文件组件(也被称为<code>.vue</code> 文件 , 英文 Single-File Components，缩写为 <strong>SFC</strong>)<br> 顾名思义，Vue 的单文件组件会将一个组件的逻辑 (JavaScript)，模板 (HTML) 和样式 (CSS) 封装在同一个文件里。</p><div class="code-group"><div class="code-group__nav"><ul class="code-group__ul"><li class="code-group__li"><button class="code-group__nav-tab code-group__nav-tab-active" ariapressed="true" ariaexpanded="true">Vue3 组合式</button></li><li class="code-group__li"><button class="code-group__nav-tab" ariapressed="false" ariaexpanded="false">Vue3 选项式</button></li></ul></div><!--[--><div class="code-group-item" aria-selected="false"><!--[--><div class="language-vue line-numbers-mode" data-ext="vue"><pre class="language-vue"><code><span class="token comment">&lt;!-- 相当于 HTML --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>count++<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>Count is: {{ count }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- 相当于 JavaScript --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> ref <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;vue&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> count <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- 相当于 CSS --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">button</span> <span class="token punctuation">{</span>
  <span class="token property">font-weight</span><span class="token punctuation">:</span> bold<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><!--]--></div><div class="code-group-item" aria-selected="false"><!--[--><div class="language-vue line-numbers-mode" data-ext="vue"><pre class="language-vue"><code><span class="token comment">&lt;!-- 写法和Vue2 基本一致 --&gt;</span>
<span class="token comment">&lt;!-- 相当于 HTML --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>count++<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>Count is: {{ count }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- 相当于 JavaScript --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  <span class="token function">data</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      <span class="token literal-property property">count</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token comment">&lt;!-- 相当于 CSS --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">button</span> <span class="token punctuation">{</span>
  <span class="token property">font-weight</span><span class="token punctuation">:</span> bold<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><!--]--></div><!--]--></div><h2 id="api-分格" tabindex="-1"><a class="header-anchor" href="#api-分格" aria-hidden="true">#</a> API 分格</h2><p>Vue组件 有两种不同的风格书写：<strong>选项式(Options API)<strong>和</strong>组合式(Composition API)</strong></p><p><strong>选项式和组合式的 区别：</strong></p><p><img src="/blogs/assets/composition-e3f2c350.png" alt="API 分格比较"></p><h2 id="创建一个-vue-项目" tabindex="-1"><a class="header-anchor" href="#创建一个-vue-项目" aria-hidden="true">#</a> 创建一个 Vue 项目</h2><blockquote><p>前提条件</p><ul><li>熟悉命令行</li><li>已安装 16.0 或者更高的 <a href="https://nodejs.org/" target="_blank" rel="noopener noreferrer">Node.js<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></li></ul></blockquote><div class="language-bash line-numbers-mode" data-ext="sh"><pre class="language-bash"><code><span class="token comment"># 步骤一：创建 Vue 项目</span>
<span class="token function">npm</span> init vue@latest

<span class="token comment"># 步骤二：安装完成后  进入 Vue 项目中</span>
<span class="token builtin class-name">cd</span> <span class="token operator">&lt;</span>your-project-name<span class="token operator">&gt;</span>

<span class="token comment"># 步骤三：安装依赖</span>
<span class="token function">npm</span> i

<span class="token comment"># 步骤四: 运行项目</span>
<span class="token function">npm</span> run dev
</code></pre><div class="highlight-lines"><br><div class="highlight-line"> </div><br><br><div class="highlight-line"> </div><br><br><div class="highlight-line"> </div><br><br><div class="highlight-line"> </div></div><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="生命周期" tabindex="-1"><a class="header-anchor" href="#生命周期" aria-hidden="true">#</a> 生命周期</h2><p>生命周期分为：<strong>四个阶段8个钩子函数</strong></p><table><thead><tr><th><strong>阶段</strong></th><th><strong>Vue2</strong></th><th><strong>Vue3选项式</strong> <br><a href="https://cn.vuejs.org/api/options-lifecycle.html#updated" target="_blank" rel="noopener noreferrer">查看文档 - 官网<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a><br><a href="https://www.w3cschool.cn/vuejs3/vuejs3-wnst3f5a.html" target="_blank" rel="noopener noreferrer">查看文档 - W3Cschool<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></th><th><strong>Vue3组合式</strong> <br><a href="https://cn.vuejs.org/api/composition-api-lifecycle.html" target="_blank" rel="noopener noreferrer">查看文档 - 官网<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a><br><a href="https://www.w3cschool.cn/vuejs3/vuejs3-ev9w3f4k.html" target="_blank" rel="noopener noreferrer">查看文档 - W3Cschool<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></th></tr></thead><tbody><tr><td><strong>初始化阶段</strong><br><br>创建前/后</td><td>beforeCreate()<br><br>created()</td><td>beforeCreate()<br><br>created()</td><td><strong>Not Needed</strong></td></tr><tr><td><strong>挂载阶段</strong><br><br>挂载前/后</td><td>beforeMount()<br><br>mounted()</td><td>beforeMount()<br><br>mounted()</td><td>onBeforeMount()<br><br>onMounted()</td></tr><tr><td><strong>更新阶段</strong><br><br>更新前/后</td><td>beforeUpdate()<br><br>updated()</td><td>beforeUpdate()<br><br>updated()</td><td>onBeforeUpdate()<br><br>onUpdated()</td></tr><tr><td><strong>销毁阶段</strong><br><br>销毁前/后</td><td>beforeDestroy()<br><br>destroyed()</td><td>beforeUnmount()<br><br>unmounted()</td><td>onBeforeUnmount()<br><br>onUnmounted()</td></tr></tbody></table><details class="custom-container details"><summary>代码 <span class="badge tip" style=""><!--[-->演示<!--]--></span></summary><div class="language-vue line-numbers-mode" data-ext="vue"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>我喜欢吃：{{ data.name }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>el-button</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>success<span class="token punctuation">&quot;</span></span> <span class="token attr-name">link</span> <span class="token attr-name">icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>EditPen<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>update<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>更新<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>el-button</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span>
  ref<span class="token punctuation">,</span>
  onBeforeMount<span class="token punctuation">,</span>
  onMounted<span class="token punctuation">,</span>
  onBeforeUpdate<span class="token punctuation">,</span>
  onUpdated<span class="token punctuation">,</span>
  onBeforeUnmount<span class="token punctuation">,</span>
  onUnmounted
<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;vue&#39;</span>

<span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span>
  <span class="token punctuation">{</span>
    <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&#39;🍎 🍇 &#39;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">)</span>

<span class="token keyword">const</span> <span class="token function-variable function">update</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  data<span class="token punctuation">.</span>value<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">&#39;🥭 🍍 🍉 🥝 🍎 🍇&#39;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 挂载阶段  进入页面时执行</span>
<span class="token function">onBeforeMount</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;挂载前&#39;</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span>value<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token function">onMounted</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;挂载后&#39;</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span>value<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token comment">// 更新阶段  点击更新按钮时执行</span>
<span class="token function">onBeforeUpdate</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;更新前&#39;</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span>value<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token function">onUpdated</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;更新后&#39;</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span>value<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token comment">// 销毁阶段  切换至其他路由时执行 </span>
<span class="token function">onBeforeUnmount</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;销毁前&#39;</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span>value<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token function">onUnmounted</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;销毁后&#39;</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span>value<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>scss<span class="token punctuation">&quot;</span></span> <span class="token attr-name">scoped</span><span class="token punctuation">&gt;</span></span><span class="token style"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="highlight-lines"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><div class="highlight-line"> </div><br><br><br><br><br><br><br><div class="highlight-line"> </div><br><br><br><br><br><br><br><div class="highlight-line"> </div><br><br><br><br><br><br><br><br><br><br></div><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><p><strong>Vue2 生命周期</strong><img src="/blogs/assets/vue2生命周期-ed3cbd2c.png" alt="Vue2 - 生命周期"><br><strong>Vue3 生命周期</strong><img src="/blogs/assets/vue3生命周期-16e4c08e.png" alt="Vue3 - 生命周期"></p><h2 id="vue-模板语法" tabindex="-1"><a class="header-anchor" href="#vue-模板语法" aria-hidden="true">#</a> Vue 模板语法</h2><p><img src="/blogs/assets/vue模板语法-7a0e57fe.png" alt="Vue - 模板语法"></p><h2 id="ref、reactive、toref、torefs" tabindex="-1"><a class="header-anchor" href="#ref、reactive、toref、torefs" aria-hidden="true">#</a> ref、reactive、toRef、toRefs</h2><p><strong>ref 函数</strong></p><blockquote><p>ref 其实也是 内部调用 reactive 来实现的</p></blockquote><ul><li>ref: 用来给<strong>基本数据类型</strong>绑定响应式数据;</li><li>在setup()函数中时，需要通过 .value 的形式获取对应的值， 在 tamplate 会自动解析,不需要 .value;</li><li><strong>参数</strong>可以传入<strong>任意数据类型</strong>;</li></ul><p><strong>reactive 函数</strong></p><blockquote><p>reactive 不能直接 解构赋值; 需要使用 toRef / toRefs</p></blockquote><ul><li>用来给<strong>复杂数据类型</strong>绑定响应式数据，直接访问即可;</li><li><strong>参数只能</strong>传入<strong>引用类型</strong>，返回一个具有响应式状态的副本;</li><li>不要直接解构使用 reactive 定义的响应式对象，否则会造成该对象脱离 ref 响应式。需要用 toRefs 将其转化为响应式数据对象，然后再解构返回。</li></ul><p><strong>reactive、ref 比较</strong></p><blockquote><p><strong>从定义数据角度对比：</strong><br> 1. ref 用来定义：基本类型数据；<br> 2. reactive 用来定义：对象（或数组）类型(引用类型)；<br> 3. 备注：ref 也可以用来定义对象（或数组）类型数据, 它内部会自动通过 reactive 转为代理对象；<br><strong>从原理角度对比：</strong><br> 1. ref 通过 Object.defineProperty() 的 get 与 set 来实现响应式（数据劫持）；<br> 2. reactive 通过使用 Proxy 来实现响应式（数据劫持）, 并通过 Reflect 操作源对象内部的数据；<br><strong>从使用角度对比：</strong><br> 1. ref 定义的数据：操作数据需要 .value，读取数据时模板中直接读取不需要 .value；<br> 2. reactive 定义的数据：操作数据与读取数据：均不需要 .value；</p></blockquote><details class="custom-container details"><summary>代码 <span class="badge tip" style=""><!--[-->演示<!--]--></span></summary><div class="language-vue line-numbers-mode" data-ext="vue"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>{{title}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>{{userInfo}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ts<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> ref<span class="token punctuation">,</span> reactive <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;vue&quot;</span><span class="token punctuation">;</span>

type Person <span class="token operator">=</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">name</span><span class="token operator">:</span> string<span class="token punctuation">;</span>
    <span class="token literal-property property">age</span><span class="token operator">:</span> number<span class="token punctuation">;</span>
    addr<span class="token operator">?</span><span class="token operator">:</span> string<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 基本数据类型</span>
<span class="token keyword">const</span> title <span class="token operator">=</span> ref<span class="token operator">&lt;</span>string<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token string">&quot;李四&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 引用数据类型</span>
<span class="token keyword">const</span> userInfo <span class="token operator">=</span> reactive<span class="token operator">&lt;</span>Person<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&#39;张三&#39;</span><span class="token punctuation">,</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">18</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><p><strong>toRef 函数</strong></p><blockquote><p>如果对象是非响应式的，数据可以改变，但视图显示数据没有更新<br> 使用toRef方法，将数据变成响应式的</p></blockquote><ul><li>toRef 接受两个参数：第一个参数为源对象，第二个参数为源对象中的属性名；</li><li>获取数据值的时候需要加 .value；</li><li>使用场景：有一个响应式对象数据，但是模版中只需要使用其中一项数据；</li><li>使用 toRef 转化后生成的 ref 数据，如果是引用类型数据时，那么它不是原始数据的拷贝，而是原始数据的引用，改变它的数据也会同时改变原始数据；</li></ul><details class="custom-container details"><summary>代码 <span class="badge tip" style=""><!--[-->演示<!--]--></span></summary><div class="language-vue line-numbers-mode" data-ext="vue"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
     <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>change<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>按钮<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
     <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>{{ obj.age }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
     <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>{{ newAge }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ts<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> reactive<span class="token punctuation">,</span> toRef <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;vue&#39;</span>

<span class="token keyword">const</span> obj <span class="token operator">=</span><span class="token function">reactive</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&#39;张三&#39;</span><span class="token punctuation">,</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">18</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token keyword">let</span> newAge <span class="token operator">=</span> <span class="token function">toRef</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span><span class="token string">&#39;age&#39;</span><span class="token punctuation">)</span>

<span class="token keyword">const</span> <span class="token function-variable function">change</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  newAge<span class="token punctuation">.</span>value<span class="token operator">++</span><span class="token punctuation">,</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;obj:&#39;</span><span class="token punctuation">,</span>obj<span class="token punctuation">,</span><span class="token string">&#39;newAge&#39;</span><span class="token punctuation">,</span>newAge<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><p><strong>toRefs 函数</strong></p><blockquote><p>toRefs相当于对，对象内每个属性调用toRef，toRefs返回的对象内的属性使用时需要加.value，还能解构使用</p></blockquote><details class="custom-container details"><summary>代码 <span class="badge tip" style=""><!--[-->演示<!--]--></span></summary><div class="language-vue line-numbers-mode" data-ext="vue"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
     <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>change<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>按钮<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
     <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>{{ obj.age }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
     <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>{{ age }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ts<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> reactive<span class="token punctuation">,</span> toRefs <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;vue&#39;</span>

<span class="token keyword">const</span> obj <span class="token operator">=</span><span class="token function">reactive</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">&#39;张三&#39;</span><span class="token punctuation">,</span>
  <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">18</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">// const newAge = toRefs(obj)</span>
<span class="token keyword">const</span> <span class="token punctuation">{</span>name<span class="token punctuation">,</span>age<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">toRefs</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span> <span class="token comment">// 解构</span>

<span class="token keyword">const</span> <span class="token function-variable function">change</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// newAge.age.value++,</span>
  age<span class="token punctuation">.</span>value<span class="token operator">++</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;obj:&#39;</span><span class="token punctuation">,</span>obj<span class="token punctuation">,</span><span class="token string">&#39;age&#39;</span><span class="token punctuation">,</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><p><strong>总结</strong></p><ul><li>ref、reactive是在 setup() 声明组件内部状态用的， 这些变量通常都要 return 出去，除了供 &lt; template &gt; 或渲染函数渲染视图，也可以作为 props 或 emit 参数 在组件间传递。它们的值变更可触发页面渲染；</li><li>toRef、toRefs 用于处理 组件/函数 传递的响应式数据，如：在接收父组件 props 时 / 或 composables 组合式函数返回数据时建立起某些属性的响应式引用；</li><li>通过 ref 包装的属性在 setup 函数内都需要通过 .value 去访问它值 ( template 模版内不用 )。因此，ref、toRef 创建的变量值都需要用变量 .value 读取。reactive 则不用，因为会自动解包分配给它的 ref。<br> 至于 toRefs，如果是解构赋值，如： const { state1, state2 } = toRefs(props)，值需要这样获取：state1.value.count；<br> 若整体赋给一个变量，如：const state = toRefs(props)，则是 state.state1.value。</li><li>只有 toRefs 可以解构；</li><li>以上四种方式声明的变量在通过 props 或 事件 传递时，均会维持其响应性；</li></ul><h2 id="vue-指令" tabindex="-1"><a class="header-anchor" href="#vue-指令" aria-hidden="true">#</a> Vue 指令</h2><h3 id="内置指令" tabindex="-1"><a class="header-anchor" href="#内置指令" aria-hidden="true">#</a> 内置指令</h3><blockquote><p>在Vue中，指令其实就是特殊的属性;<br> Vue会根据指令，在背后做一些事，至于具体做什么事，Vue根据不同的指令会执行不同的操;<br> Vue指令有个明显的特点就是，都是以 <strong>v-开头</strong>。</p></blockquote><table><thead><tr><th>名称</th><th>作用</th></tr></thead><tbody><tr><td>v-text</td><td>用于更新元素的 textContent</td></tr><tr><td>v-html</td><td>用于更新元素的 innerHTML</td></tr><tr><td>v-show</td><td>根据表达式的真假值，切换元素的display值，用于控制元素的展示和隐藏</td></tr><tr><td>v-if</td><td>根据表达式的真假值来有条件地渲染元素<br>与v-show相比，v-if在切换时是元素的销毁或重建，而不是简单的显示隐藏</td></tr><tr><td>v-else-if</td><td>表示 v-if 的“else if 块”，和v-else一样，前一个兄弟元素必须有v-if或 v-else-if</td></tr><tr><td>v-for</td><td>v-for一个用于迭代的指令，可以根据源数据多次渲染元素或模板块<br>也可以为数组索引指定别名或者用于对象的键<br>需要和 <strong>key关键字</strong> 搭配使用</td></tr><tr><td>v-on</td><td>v-on用于给元素绑定事件，可以缩写为：@ <br> eg:@click=&quot;事件名称&quot; / @click.stop=&quot;事件名称&quot;(停止冒泡)</td></tr><tr><td>v-bind</td><td>用于动态绑定数据和元素属性，可以缩写为: 或.(当使用 .prop 修饰符时)</td></tr><tr><td>v-model</td><td>双向绑定</td></tr><tr><td>v-slot</td><td>v-slot用于提供具名插槽或需要接收 prop 的插槽<br>可选择性传递参数，表示插槽名，默认值default</td></tr><tr><td>v-pre</td><td>跳过这个元素及其子元素的编译过程; 也就是里面的数据不会被编译</td></tr><tr><td>v-cloak</td><td>解决插值表达式在页面闪烁问题</td></tr><tr><td>v-once</td><td>表示只渲染一次，当要重新渲染，元素/组件及其所有的子节点将被视为静态内容并跳过</td></tr></tbody></table><p><strong>补充</strong></p><ul><li>v-show: <strong>不支持 <code>&lt;template&gt;</code></strong> 元素，也不支持 v-else</li><li>v-if: 与v-show相比，v-if在切换时是元素的销毁或重建，而不是简单的显示隐藏; 并且v-if可以是 <code>&lt;template&gt;</code>，如果元素是 <code>&lt;template&gt;</code>，将提取它的内容作为条件块</li><li>v-on 可以缩写为 @ 常见的修饰符有</li></ul><p>.stop - 调用 event.stopPropagation()</p><p>.prevent - 调用 event.preventDefault()</p><p>.capture - 添加事件侦听器时使用 capture 模式</p><p>.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调</p><p>.{keyAlias} - 仅当事件是从特定键触发时才触发回调</p><p>.once - 只触发一次回调</p><p>.left - 只当点击鼠标左键时触发</p><p>.right - 只当点击鼠标右键时触发</p><p>.middle - 只当点击鼠标中键时触发</p><p>.passive - { passive: true } 模式添加侦听器</p><details class="custom-container details"><summary>代码 <span class="badge tip" style=""><!--[-->演示<!--]--></span></summary><div class="language-vue line-numbers-mode" data-ext="vue"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">v-text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>textContent<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">v-html</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>htmlContent<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span> 

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">v-show</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>isShow<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>嗨 你好呀!<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>isShow<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>嗨 你好呀! isShow为真显示,反之则反<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span>  <span class="token attr-name">v-else</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>isShow<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>嗨 你好呀!  isShow为真隐藏,反之则反<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>

    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item in data<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.id<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.name}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- item: 每一个对象    index: 索引下标    array: 原始数据 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>(item , index , array) in data<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.id<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.name}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> ref <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;vue&#39;</span>

<span class="token keyword">const</span> textContent <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token string">&#39;这就是一个文本内容&#39;</span><span class="token punctuation">)</span>

<span class="token comment">// 需要注意: 里头内容必须是按普通 HTML 插入</span>
<span class="token keyword">const</span> htmlContent <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token string">&#39;&lt;span&gt;嗨  你好呀!&lt;/span&gt;&#39;</span><span class="token punctuation">)</span>

<span class="token comment">// 需要注意：v-show 不支持 &lt;template&gt; 元素，也不支持 v-else</span>
<span class="token comment">// v-if是直接销毁元素，而v-show只是视觉上隐藏了而已</span>
<span class="token comment">// 并且v-if可以是 &lt;template&gt;，如果元素是 &lt;template&gt;，将提取它的内容作为条件块</span>
<span class="token comment">// 需要注意：v-else前一个兄弟元素必须有 v-if 或 v-else-if</span>
<span class="token keyword">const</span> isShow <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>

<span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    <span class="token literal-property property">id</span><span class="token operator">:</span><span class="token string">&#39;123&#39;</span><span class="token punctuation">,</span>
    <span class="token literal-property property">name</span><span class="token operator">:</span><span class="token string">&#39;张三&#39;</span><span class="token punctuation">,</span>
    <span class="token literal-property property">age</span><span class="token operator">:</span><span class="token string">&#39;18&#39;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    <span class="token literal-property property">id</span><span class="token operator">:</span><span class="token string">&#39;456&#39;</span><span class="token punctuation">,</span>
    <span class="token literal-property property">name</span><span class="token operator">:</span><span class="token string">&#39;李四&#39;</span><span class="token punctuation">,</span>
    <span class="token literal-property property">age</span><span class="token operator">:</span><span class="token string">&#39;20&#39;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">)</span>

</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><h3 id="自定义指令" tabindex="-1"><a class="header-anchor" href="#自定义指令" aria-hidden="true">#</a> 自定义指令</h3><blockquote><p>需要熟悉的知识点: <a href="https://www.runoob.com/jsref/dom-obj-all.html" target="_blank" rel="noopener noreferrer">DOM 元素 属性和方法<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a><br> 逻辑复用<br> 自定义指令: <strong>局部自定义指令</strong> 和 <strong>全局自定义指令</strong>(推荐)<br> 使用场景: 权限控制...</p></blockquote><p><strong>指令钩子</strong><br> 一个指令的定义对象可以提供几种钩子函数 (都是可选的)：</p><blockquote><p>有7个钩子指令函数: 创建后created() 挂载前beforeMount() 挂载后mounted() 更新前beforeUpdate() 更新后updated() 销毁前beforeUnmount() 销毁后unmounted</p></blockquote><details class="custom-container details"><summary>指令钩子 <span class="badge tip" style=""><!--[-->函数<!--]--></span></summary><div class="language-javascript line-numbers-mode" data-ext="js"><pre class="language-javascript"><code><span class="token keyword">const</span> myDirective <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">// 在绑定元素的 attribute 前</span>
  <span class="token comment">// 或事件监听器应用前调用</span>
  <span class="token function">created</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding<span class="token punctuation">,</span> vnode<span class="token punctuation">,</span> prevVnode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token comment">// 在元素被插入到 DOM 前调用</span>
  <span class="token function">beforeMount</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding<span class="token punctuation">,</span> vnode<span class="token punctuation">,</span> prevVnode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token comment">// 在绑定元素的父组件</span>
  <span class="token comment">// 及他自己的所有子节点都挂载完成后调用</span>
  <span class="token function">mounted</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding<span class="token punctuation">,</span> vnode<span class="token punctuation">,</span> prevVnode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token comment">// 绑定元素的父组件更新前调用</span>
  <span class="token function">beforeUpdate</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding<span class="token punctuation">,</span> vnode<span class="token punctuation">,</span> prevVnode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token comment">// 在绑定元素的父组件</span>
  <span class="token comment">// 及他自己的所有子节点都更新后调用</span>
  <span class="token function">updated</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding<span class="token punctuation">,</span> vnode<span class="token punctuation">,</span> prevVnode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token comment">// 绑定元素的父组件卸载前调用</span>
  <span class="token function">beforeUnmount</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding<span class="token punctuation">,</span> vnode<span class="token punctuation">,</span> prevVnode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token comment">// 绑定元素的父组件卸载后调用</span>
  <span class="token function">unmounted</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding<span class="token punctuation">,</span> vnode<span class="token punctuation">,</span> prevVnode</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// 钩子参数</span>
<span class="token comment">// el：指令绑定到的元素。这可以用于直接操作 DOM。</span>

<span class="token comment">// binding：一个对象，包含以下属性。</span>
<span class="token comment">// 1.value：传递给指令的值。例如在 v-my-directive=&quot;1 + 1&quot; 中，值是 2。</span>
<span class="token comment">// 2.oldValue：之前的值，仅在 beforeUpdate 和 updated 中可用。无论值是否更改，它都可用。</span>
<span class="token comment">// 3.arg：传递给指令的参数 (如果有的话)。例如在 v-my-directive:foo 中，参数是 &quot;foo&quot;。</span>
<span class="token comment">// 4.modifiers：一个包含修饰符的对象 (如果有的话)。例如在 v-my-directive.foo.bar 中，修饰符对象是 { foo: true, bar: true }。</span>
<span class="token comment">// 5.instance：使用该指令的组件实例。</span>
<span class="token comment">// 6.dir：指令的定义对象。</span>

<span class="token comment">// vnode：代表绑定元素的底层 VNode。</span>

<span class="token comment">// prevNode：代表之前的渲染中指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。</span>
</code></pre><div class="highlight-lines"><br><br><br><div class="highlight-line"> </div><br><br><div class="highlight-line"> </div><br><br><br><div class="highlight-line"> </div><br><br><div class="highlight-line"> </div><br><br><br><div class="highlight-line"> </div><br><br><div class="highlight-line"> </div><br><br><div class="highlight-line"> </div><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></div><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><p><strong>全局自定义指令</strong></p><p><a href="https://blog.csdn.net/lijiahui_/article/details/122709889" target="_blank" rel="noopener noreferrer">app.directive(参数一, 参数二)<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p><details class="custom-container details"><summary>代码 <span class="badge tip" style=""><!--[-->演示<!--]--></span></summary><div class="language-javascript line-numbers-mode" data-ext="js"><pre class="language-javascript"><code><span class="token comment">// 在 src 目录下 创建directives</span>
<span class="token comment">// src</span>
<span class="token comment">// |---directives</span>
<span class="token comment">//     |---index.js</span>
<span class="token comment">//     |---modules</span>
<span class="token comment">//         |---copy.js</span>
<span class="token comment">// |---main.js</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>步骤一: copy.js 定义复制指令</p><div class="language-javascript line-numbers-mode" data-ext="js"><pre class="language-javascript"><code><span class="token comment">// 1.可以使用 VueUse 里面的 useClipboard() 函数  see: https://www.vueusejs.com/core/useClipboard/</span>

<span class="token comment">// 2.自定义指令</span>

<span class="token comment">// 复制指令</span>
<span class="token doc-comment comment">/**
 * v-copy
 * 复制某个值至剪贴板
 * 接收参数：string类型/Ref&lt;string&gt;类型/Reactive&lt;string&gt;类型
 */</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> ElMessage <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;element-plus&#39;</span>

<span class="token keyword">const</span> copy <span class="token operator">=</span> <span class="token punctuation">{</span>
    <span class="token comment">// 指令钩子函数有 7个指令钩子函数</span>
    <span class="token comment">// 创建后 挂载前 挂载后 更新前 更新后 销毁前 销毁后</span>

    <span class="token comment">// 挂载后</span>
    <span class="token function">mounted</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 步骤一: 将指令绑定的值 赋值给el</span>
        el<span class="token punctuation">.</span>copyData <span class="token operator">=</span> binding<span class="token punctuation">.</span>value

        <span class="token comment">// 步骤二: 对dom元素添加事件监听</span>
        el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">&#39;click&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
            <span class="token comment">// 步骤1: 没有数据 出现提示信息</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>el<span class="token punctuation">.</span>copyData<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">ElMessage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">message</span><span class="token operator">:</span> <span class="token string">&#39;暂无内容&#39;</span><span class="token punctuation">,</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">&#39;warning&#39;</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>

            <span class="token comment">// 步骤2: 有数据 执行赋值操作 DOM相关操作</span>

            <span class="token comment">// 步骤2.1: 创建一个元素</span>
            <span class="token keyword">const</span> input <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">&#39;input&#39;</span><span class="token punctuation">)</span>

            <span class="token comment">// 步骤2.2: 将值赋值给input元素</span>
            input<span class="token punctuation">.</span>value <span class="token operator">=</span> el<span class="token punctuation">.</span>copyData

            <span class="token comment">// 步骤2.3: 末尾添加一个子节点</span>
            document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">// 步骤2.4: 对input里面的内容进行选中</span>
            input<span class="token punctuation">.</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">// 步骤2.5 对选中的内容进行复制</span>
            document<span class="token punctuation">.</span><span class="token function">execCommand</span><span class="token punctuation">(</span><span class="token string">&quot;Copy&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">// 步骤2.6 将 删除 input节点</span>
            document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">// 步骤2.7 提示信息</span>
            <span class="token function">ElMessage</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
                <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">&quot;success&quot;</span><span class="token punctuation">,</span>
                <span class="token literal-property property">message</span><span class="token operator">:</span> <span class="token string">&quot;复制成功&quot;</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>

    <span class="token comment">// 更新后</span>
    <span class="token function">updated</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> binding</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 步骤三: 将指令更新后的值 赋值给el</span>
        el<span class="token punctuation">.</span>copyData <span class="token operator">=</span> binding<span class="token punctuation">.</span>value
    <span class="token punctuation">}</span><span class="token punctuation">,</span>

    <span class="token comment">// 销毁后</span>
    <span class="token function">unmounted</span><span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 步骤四: 取消监听</span>
        <span class="token comment">// 一般在组件中使用addeventlistener添加 事件监听 的时候，在组件销毁的时候都要使用removeEventListener进行销毁，不然会造成内存泄漏。</span>
        el<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">&quot;click&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// 步骤五: 导出</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> copy<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>步骤二: index.js 引入modules下面的所有指令</p><div class="language-javascript line-numbers-mode" data-ext="js"><pre class="language-javascript"><code><span class="token keyword">import</span> copy <span class="token keyword">from</span> <span class="token string">&quot;./modules/copy&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> directivesList <span class="token operator">=</span> <span class="token punctuation">{</span>
    copy<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> directives <span class="token operator">=</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">install</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// Object.keys 是 JavaScript 中的一个方法，用于获取一个对象中所有可枚举属性的键值，返回一个由键组成的数组。</span>
        Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>directivesList<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">key</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
            <span class="token comment">// app.directive(参数一, 参数二) see: https://blog.csdn.net/lijiahui_/article/details/122709889</span>
            app<span class="token punctuation">.</span><span class="token function">directive</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> directivesList<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> directives<span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>步骤三: main.js 引入directives===&gt;index.js 所有的指令</p><div class="language-javascript line-numbers-mode" data-ext="js"><pre class="language-javascript"><code><span class="token comment">// 部分代码</span>
<span class="token keyword">import</span> directives <span class="token keyword">from</span> <span class="token string">&quot;@/directives/index&quot;</span><span class="token punctuation">;</span>

app<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>directives<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">mount</span><span class="token punctuation">(</span><span class="token string">&quot;#app&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>步骤四: 去 组件中使用 无需引入 可以直接使用</p><div class="language-vue line-numbers-mode" data-ext="vue"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>el-input</span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>data<span class="token punctuation">&quot;</span></span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>请输入内容<span class="token punctuation">&quot;</span></span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token value css language-css"><span class="token property">width</span><span class="token punctuation">:</span> 500px</span><span class="token punctuation">&quot;</span></span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#append</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>el-button</span> <span class="token attr-name">v-copy</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>data<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span> 复制 <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>el-button</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>el-input</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> ref <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;vue&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token string">&quot;我是被复制的内容 🍒 🍉 🍊&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><h2 id="插槽-slots" tabindex="-1"><a class="header-anchor" href="#插槽-slots" aria-hidden="true">#</a> 插槽 Slots</h2><p><a href="https://cn.vuejs.org/guide/components/slots.html" target="_blank" rel="noopener noreferrer">参考文档 - 官网<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a><br><a href="https://blog.csdn.net/m0_53022813/article/details/124441064" target="_blank" rel="noopener noreferrer">参考文档<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p><p>若插槽有默认值 并且 没有传递插槽值, 则会执行插槽的默认值;<br> 若插槽有默认值 并且 传递了插槽值, 则会执行传递的插槽值.</p><p>没有指定 name 名称的插槽，会有隐含的名称叫做 &quot;default&quot;.</p><h3 id="默认插槽" tabindex="-1"><a class="header-anchor" href="#默认插槽" aria-hidden="true">#</a> 默认插槽</h3><p><img src="/blogs/assets/插槽-dbdaf1e8.png" alt="插槽"></p><h3 id="具名插槽" tabindex="-1"><a class="header-anchor" href="#具名插槽" aria-hidden="true">#</a> 具名插槽</h3><blockquote><p>没有指定 name 名称的插槽，会有隐含的名称叫做 &quot;default&quot;, 即 默认插槽</p></blockquote><p><img src="/blogs/assets/具名插槽-ebb7b207.png" alt="具名插槽"></p><h3 id="作用域插槽" tabindex="-1"><a class="header-anchor" href="#作用域插槽" aria-hidden="true">#</a> 作用域插槽</h3><p><img src="/blogs/assets/作用域插槽-36a52821.svg" alt="作用域"></p><h2 id="透传" tabindex="-1"><a class="header-anchor" href="#透传" aria-hidden="true">#</a> 透传</h2><p><a href="https://cn.vuejs.org/guide/components/attrs.html" target="_blank" rel="noopener noreferrer">透传 Attributes 文档<span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span></a></p><p><strong>透传 attribute</strong>指的是传递给一个组件，却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id。</p><details class="custom-container details"><summary>透传 <span class="badge tip" style=""><!--[-->使用场景<!--]--></span></summary><div class="language-javascript line-numbers-mode" data-ext="js"><pre class="language-javascript"><code><span class="token comment">// 1. class style id 即样式</span>

<span class="token comment">// 2. 使用组件库 封装组件 需要自身的props、方法和事件 (特别适用)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><p><strong>禁用 Attributes 继承</strong></p><p>如果你<strong>不想要</strong>一个组件自动地继承 attribute，你可以在组件选项中设置 inheritAttrs: false。</p><details class="custom-container details"><summary>Attributes 继承 <span class="badge tip" style=""><!--[-->禁用<!--]--></span></summary><div class="language-javascript line-numbers-mode" data-ext="js"><pre class="language-javascript"><code><span class="token operator">&lt;</span>script setup<span class="token operator">&gt;</span>
<span class="token function">defineOptions</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">inheritAttrs</span><span class="token operator">:</span> <span class="token boolean">false</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">// ...setup 逻辑</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">&gt;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></details><p><strong>单节点和多节点注意事项</strong></p><p>和单根节点组件有所不同，有着多个根节点的组件没有自动 attribute 透传行为。如果 $attrs 没有被显式绑定，将会抛出一个运行时警告。</p><blockquote><p>有 <strong>多个节点</strong> 时使用: <strong>v-bind=&quot;$attrs&quot;</strong> 绑定在<strong>单独的一个节点</strong>上面, 进行透传</p><p>使用 <strong>v-for=&quot;item in allProps&quot;</strong> 遍历时: <strong>v-bind=&quot;item&quot;</strong>, 进行透传</p></blockquote></div><!--[--><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">上次更新: </span><!----></div><div class="meta-item contributors"><span class="meta-item-label">作者: </span><span class="meta-item-info"><!--[--><!--[--><span class="contributor" title="email: fayuanaini@dingtalk.com">fayuan</span><!----><!--]--><!--]--></span></div></footer><!----><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
    <script type="module" src="/blogs/assets/app-5598dde8.js" defer></script>
  </body>
</html>
